<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>模型设计</title>
    <link rel="stylesheet" href="../../../../component/pear/css/pear.css"/>
    <link rel="stylesheet" href="../../../../admin/css/reset.css"/>
    <!--LogicFlow core包css-->
    <link rel="stylesheet" href="../../../../logicflow/core/dist/style/index.css"/>
    <!--LogicFlow extension包css-->
    <link rel="stylesheet" href="../../../../logicflow/extension/lib/style/index.css"/>
</head>
<style>
    * {
        padding: 0;
        margin: 0;
    }

    html, body {
        overflow: hidden;
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
    }

    .lf-control-see {
        background-image: url('');
    }

    .lf-control-import {
        background-image: url('');
    }

    .lf-control-clear {
        background-image: url('');
    }

    .lf-control-save {
        background-image: url('');
    }

    .lf-control-refresh {
        background-image: url("");
    }

    .lf-control-exit {
        background-image: url('');
    }


    .custom-minimap {
        background-image: url();
    }

    #lf-graph {
        margin: 20px 20px 0px 20px;
        width: 98%;
        height: 100%;
    }


    /*tab title*/
    .drawer-section-list ul li {
        display: inline-block;
        zoom: 1;
        vertical-align: top;
        margin-right: 20px;
        font-size: 16px;
        line-height: 34px;
        color: #373d40;
        cursor: pointer;
    }

    /*选中下划线*/
    .drawer-section-list ul .on {
        color: #488bff;
        border-bottom: 1px solid #488bff;
    }

    /*列表*/
    .drawer-section-info div {
        text-align: left;
        border-top: 1px solid #ececec;
    }

</style>
<body>

<!--画板-->
<div id="lf-graph"></div>

<!--layui依赖-->
<script src="../../../../component/layui/layui.js"></script>
<script src="../../../../component/pear/pear.js"></script>
<script src="../../../../lms/base64.js"></script>
<script src="../../../../lms/common.js"></script>
<script src="../../../../lms/permission.js"></script>
<script src="../../../../lms/config.js"></script>


<script type="text/javascript" src="../../../../logicflow/core/dist/logic-flow.js"></script>
<!--LogicFlow的插件引入-->
<script type="text/javascript" src="../../../../logicflow/extension/lib/Menu.js"></script>
<script type="text/javascript" src="../../../../logicflow/extension/lib/DndPanel.js"></script>
<script type="text/javascript" src="../../../../logicflow/extension/lib/Control.js"></script>
<script type="text/javascript" src="../../../../logicflow/extension/lib/MiniMap.js"></script>
<script type="text/javascript" src="../../../../logicflow/extension/lib/Group.js"></script>
<!--LogicFlow定制模型引入-->
<script type="text/javascript" src="../../../../logicflow/customized/start.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/task.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/fork.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/join.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/subProcess.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/wfSubProcess.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/end.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/custom.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/decision.js"></script>
<script type="text/javascript" src="../../../../logicflow/customized/transition.js"></script>

<script>
    const PRIMARY_KEY = "id";
    const SAVE_URL = "/app/workflow/designer/save";
    const PANEL_URL = './panel/index.html';
    const RESTFUL_API = lms_config.api_url + "/adminapi/wf/designer";
    let $ = layui.jquery;
    let id = getQueryString('id')

    /**
     * 流程数据
     * @type {{expireTime: string, nodes: *[], displayName: string, name: string, edges: *[], instanceUrl: string}}
     */
    let graphData = {};

    if (getQueryString('operation') == 'design') {
        get()
    }


    /**
     * 创建LF实例
     * @type {LogicFlow}
     */
    const lf = new LogicFlow({
        container: document.querySelector("#lf-graph"),
        grid: {
            size: 20,
            visible: true,
            type: 'dot',
            config: {
                color: '#ababab',
                thickness: 1,
            },
        },
        plugins: [Menu, DndPanel, Control, MiniMap, Group],
        keyboard: {
            enabled: true,//是否启用快捷键
            shortcuts: [
                {
                    keys: ["del"],
                    callback: () => {
                        if (!lf) return;
                        const elements = lf.getSelectElements(true);
                        lf.clearSelectElements();
                        elements.edges.forEach((edge) => lf.deleteEdge(edge.id));
                        elements.nodes.forEach((node) => lf.deleteNode(node.id));
                    }
                }
            ]
        }
    });

    /**
     *  控制面板-清空画布
     */
    lf.extension.control.addItem({
        iconClass: 'lf-control-clear',
        title: 'clear',
        text: '清空',
        onClick: () => {
            lf.clearData()
        }
    })

    /**
     * 控制面板-添加查看按钮
     */
    lf.extension.control.addItem({
        iconClass: 'lf-control-see',
        title: '',
        text: '查看',
        onClick: () => {
            layui.use(['layer'], function () {
                let layer = layui.layer;
                layer.open({
                    type: 2,
                    area: ['800px', '500px'],
                    title: '查看流程数据',
                    maxmin: true,
                    shade: 0.1,
                    shadeClose: true,
                    content: 'panel/detail.html',
                    success: function (layero, index) {
                        // 将数据传递给子页面
                        let iframeWin = window[layero.find('iframe')[0]['name']];
                        iframeWin.child(getGraphData());
                    }, end: function (layero, index) {

                    }
                });
            })
        }
    })

    /**
     *   控制面板-添加导入按钮
     */
    lf.extension.control.addItem({
        iconClass: 'lf-control-import',
        title: '',
        text: '导入',
        onClick: () => {
            layui.use(['layer'], function () {
                let layer = layui.layer;
                layer.open({
                    type: 2,
                    area: ['800px', '500px'],
                    maxmin: true,
                    title: '导入流程数据(json)',
                    shade: 0.1,
                    shadeClose: true,
                    anim: 0,
                    content: 'panel/import.html',
                    success: function (layero, index) {
                    }, end: function (layero, index) {
                    }
                });
            })
        }
    })

    /**
     *   控制面板-刷新
     */
    lf.extension.control.addItem({
        iconClass: 'lf-control-refresh',
        title: '',
        text: '刷新',
        onClick: () => {
            location.replace(location.href)
        }
    })

    /**
     *  控制面板-保存
     */
    lf.extension.control.addItem({
        iconClass: 'lf-control-save',
        title: '',
        text: '保存',
        onClick: () => {
            saveGraphData();
        }
    })

    /**
     *   退出设计
     */
    lf.extension.control.addItem({
        iconClass: "lf-control-exit",
        title: "",
        text: "退出",
        onClick: (lf, ev) => {
            layer.confirm('确认要退出吗？', function (index) {
                //弹出层
                // var index = parent.layer.getFrameIndex(window.name);
                // parent.layer.close(index);
                //关闭当前TAB
                parent.layui.admin.closeCurrentTab()
            })
        }
    });

    /**
     *  小地图
     */
    lf.extension.control.addItem({
        iconClass: "custom-minimap",
        title: "",
        text: "导航",
        onClick: (lf, ev) => {
            const position = lf.getPointByClient(ev.x, ev.y);
            lf.extension.miniMap.show(
                position.domOverlayPosition.x - 125,
                position.domOverlayPosition.y + 40
            );
        }
    });

    /**
     *  设置默认边名称
     */
    lf.setDefaultEdgeType('workingflower:transition')
    /**
     *  设置拖拽面板
     */
    lf.extension.dndPanel.setPatternItems([
        {
            type: 'workingflower:start',
            text: '开始',
            label: '开始节点',
            properties: {},
            icon: ''
        },
        {
            type: 'workingflower:task',
            text: '用户',
            label: '用户任务',
            properties: {
                assignee: "",
                back_permission: "1",
                perform_type: "ANY",
                scope: "1",
                task_type: "Major",
                field: {}
            },
            icon: '',
            className: 'important-node'
        },
        {
            type: 'workingflower:custom',
            text: '自定义任务',
            label: '自定义任务',
            properties: {},
            icon: '',
            className: 'import_icon'
        },
        {
            type: 'workingflower:decision',
            label: '条件判断',
            properties: {},
            icon: ''
        },
        {
            type: 'workingflower:fork',
            label: '分支',
            properties: {},
            icon: ''
        },
        {
            type: 'workingflower:join',
            label: '合并',
            properties: {},
            icon: ''
        },
        {
            type: 'workingflower:end',
            text: '结束节点',
            label: '结束节点',
            properties: {},
            icon: ''
        },
        {
            type: 'workingflower:wfSubProcess',
            text: '子流程',
            label: '子流程',
            properties: {},
            icon: '',
            className: 'import_icon'
        },
        // {
        //     type: 'workingflower:subProcess',
        //     text: '',
        //     label: '子流程',
        //     properties: {},
        //     icon: '',
        //     className: 'import_icon'
        // }
    ])

    /**
     * 重新右键菜单栏目
     */
    lf.extension.menu.setMenuConfig({
        nodeMenu: [
            {
                text: "删除",
                callback(node) {
                    lf.deleteNode(node.id);
                },
            },
            {
                text: "编辑文本",
                callback: (node) => {
                    lf.editText(node.id);
                }
            },
            {
                text: "属性",
                callback(node) {
                    let e = {};
                    e.data = node;
                    propertiesPanel(e)

                }
            }
        ],
        edgeMenu: [
            {
                text: "删除",
                callback(edge) {
                    lf.deleteEdge(edge.id);
                },
            },
            {
                text: "编辑文本",
                callback: (edge) => {
                    lf.editText(edge.id);
                }
            },
            {
                text: "属性",
                callback(edge) {
                    let e = {};
                    e.data = edge;
                    propertiesPanel(e)
                }
            }
        ],
        graphMenu: [], // 重新右键菜单空跟false 一样
    });

    // 空白区右键事件-弹出流程属性表单
    const eventCenter = lf.graphModel.eventCenter
    eventCenter.on('blank:contextmenu', (args) => {
        let data = {
            name: ('name' in graphData) ? graphData.name : '',
            display_name: ('display_name' in graphData) ? graphData.display_name : '',
            expire_time: ('expire_time' in graphData) ? graphData.expire_time : '',
            instance_url: ('instance_url' in graphData) ? graphData.instance_url : '',
            instance_no_class: ('instance_no_class' in graphData) ? graphData.instance_no_class : '',
            type: 'workingflower:process'
        }
        let param = [];
        param['data'] = data;
        propertiesPanel(param)
    })


    lf.on('node:click', (data) => {
        propertiesPanel(data)
    })

    /**
     * 属性面板
     * @param data
     */
    function propertiesPanel(data) {
        layer.open({
            type: 2,
            offset: 'r',
            area: ['500px', '100%'],
            title: false,
            shade: 0.1,
            closeBtn: 0,
            shadeClose: true,
            anim: -1,
            skin: 'layer-anim-right',
            move: false,
            content: PANEL_URL,
            success: function (layero, index) {
                let iframe = window['layui-layer-iframe' + index]; // 找到iframe层
                iframe.window.child(data);
            },
            end: function () {
            }
        });
    }

    /**
     * 边线点击事件
     */
    lf.on('edge:click', (data) => {
        layui.use(['layer'], function () {
            let layer = layui.layer;
            layer.open({
                type: 2,
                offset: 'r',
                area: ['500px', '100%'],
                title: false,
                shade: 0.1,
                closeBtn: 0,
                shadeClose: true,
                anim: -1,
                skin: 'layer-anim-right',
                move: false,
                content: PANEL_URL,
                success: function (layero, index) {
                    // 将数据传递给子页面
                    let iframeWin = window[layero.find('iframe')[0]['name']];
                    iframeWin.child(data);
                }, end: function (layero, index) {

                }
            });
        })
    })


    /**
     * 处理表单数据
     * @param e
     * @returns {boolean}
     */
    function handlePropertyChange(e) {
        try {
            let type = extractValueAfterDelimiter(e.type, ':');
            if (type === 'process') {
                $.each(e, function (index, item) {
                    graphData[index] = item
                })
            } else if (type === 'subProcess') {
                $.each(e, function (index, item) {
                    if (in_array(index, ['id', 'x', 'y', 'text'])) {
                        return true;
                    }
                    lf.setProperties(e.id, {
                        [index]: item
                    })
                });
            } else if (in_array(type, ['start', 'fork', 'join', 'end', 'task', 'decision', 'custom','wfSubProcess'])) {
                if (null != e.display_name) {
                    lf.updateText(e.id, e.display_name)
                }
                //写入扩展属性
                $.each(e, function (index, item) {
                    if (in_array(index, ['id', 'display_name', 'type', 'x', 'y', 'text'])) {
                        return true;
                    }
                    lf.setProperties(e.id, {
                        [index]: item
                    })
                });
                //重新渲染
                lf.render(getGraphData())
            } else if (type === 'transition') {
                if (null != e.display_name) {
                    lf.updateText(e.id, e.display_name)
                }
                //写入扩展属性
                $.each(e, function (index, item) {
                    if (in_array(index, ['id', 'display_name', 'type', 'x', 'y', 'text'])) {
                        return true;
                    }
                    lf.setProperties(e.id, {
                        [index]: item
                    })
                });
            }
            return true;
        } catch (e) {
            return false;
        }
    }


    /**
     * 图形注册
     */
    lf.register(Task);
    lf.register(Fork);
    lf.register(Start);
    lf.register(Decision);
    lf.register(End);
    lf.register(Join);
    lf.register(Custom);
    lf.register(SubProcess);
    lf.register(WfSubProcess);
    lf.register(Transition);

    /**
     * 数据处理
     * @returns {any}
     */
    function getGraphData() {
        return {
            name: ('name' in graphData) ? graphData.name : '',
            display_name: ('display_name' in graphData) ? graphData.display_name : '',
            expire_time: ('expire_time' in graphData) ? graphData.expire_time : '',
            instance_url: ('instance_url' in graphData) ? graphData.instance_url : '',
            instance_no_class: ('instance_no_class' in graphData) ? graphData.instance_no_class : '',
            type: 'workingflower:process',
            ...lf.getGraphData()
        }
    }

    lf.render(graphData)


    /**
     *
     * @type {{process: string, fork: string, subProcess: string, task: string, decision: string, custom: string, start: string, ignore: string, end: string, join: string, transition: string}}
     */
    const NodeTypeEnum = {
        process: 'workingflower:process',
        custom: 'workingflower:custom',
        decision: 'workingflower:decision',
        end: 'workingflower:end',
        fork: 'workingflower:fork',
        join: 'workingflower:join',
        start: 'workingflower:start',
        task: 'workingflower:task',
        transition: 'workingflower:transition',
        subProcess: 'workingflower:subProcess',
        wfSubProcess: 'workingflower:wfSubProcess',
        ignore: 'workingflower:ignore'
    }

    /**
     * 对传入类型进行截取
     * @param string
     * @param delimiter
     * @returns {*}
     */
    function extractValueAfterDelimiter(string, delimiter) {
        // 找到冒号在字符串中的位置
        let delimiterIndex = string.indexOf(delimiter);
        // 如果冒号存在于字符串中，则截取冒号后面的值
        if (delimiterIndex !== -1) {
            let value = string.slice(delimiterIndex + delimiter.length);
            return value;
        } else {
            return string;
        }
    }

    /**
     * 保存设计
     */
    function saveGraphData() {
        $.ajax({
            type: 'POST',
            url: RESTFUL_API + "/save_define",
            dateType: "json",
            contentType: 'application/json',
            data: JSON.stringify({id: getQueryString(PRIMARY_KEY), content: getGraphData()}),
            success: function (ret) {
                if (ret.status === 200) {
                    layer.msg(ret.msg, {icon: 1, time: 1500}, function () {
                        // var index = parent.layer.getFrameIndex(window.name);
                        // parent.refresh();
                        // parent.layer.close(index);
                    });
                } else {
                    layer.msg(ret.msg, {icon: 2, time: 1000});
                }
            },
        });
    }

    /**
     * 获取详情
     */
    function get() {
        layui.$.ajax({
            url: RESTFUL_API + '/' + getQueryString(PRIMARY_KEY),
            type: 'GET',
            dataType: 'json',
            async: false,
            success: function (ret) {
                if (ret.status == 200) {
                    graphData = ret.data['variable'] ?? {};
                }
            },
            error: function (ret) {

            },
        });
    }

    /**
     * 导入流程数据
     * @param data
     */
    function importProcessData(data) {
        graphData = data;
        lf.render(graphData)
    }

</script>

</body>
</html>
